﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using Als.Common.Extensions;
using Als.Common.Net;
using Als.Common.String;

namespace Als.Common.Data
{
    /// <summary>
    /// 分页扩展
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PageList<T> where T : class
    {
        /// <summary>
        /// 数据分页
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页项</param>
        /// <param name="totalCount">总数</param>
        /// <param name="items">元素</param>
        public PageList(int pageIndex, int pageSize, int totalCount, List<T> items)
        {
            Total = totalCount;
            PageSize = pageSize;
            PageIndex = pageIndex;
            Items = items;
            TotalPage = Total % PageSize == 0 ? Total / PageSize : Total / PageSize + 1;
        }

        /// <summary>
        /// 总数
        /// </summary>
        public int Total { get; }

        /// <summary>
        /// 元素
        /// </summary>
        public List<T> Items { get; }


        /// <summary>
        /// 页项
        /// </summary>
        public int PageSize { get; }

        /// <summary>
        /// 页码
        /// </summary>
        public int PageIndex { get; }

        /// <summary>
        /// 总页数
        /// </summary>
        public int TotalPage { get; }

        /// <summary>
        /// 是否有上一页
        /// </summary>
        public bool HasPrev => PageIndex > 1;

        /// <summary>
        /// 是否有下一页
        /// </summary>
        public bool HasNext => PageIndex < TotalPage;
    }

    public static class PageNav
    {
        private static string Currentlastpageclass = "class='pre disable'";
        private static string Lastpageclass = "class='pre'";
        private static string Currentnumclass = "class='curr'";
        private static string Numclass = "class='num'";
        private static string Currentnextpageclass = "class='next disable'";
        private static string Nextpageclass = "class='next'";

        /// <summary>
        /// 分页HTML 只能在Action中使用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static PageResult<T> GetPage<T>(this List<T> items, int pageIndex, int pageSize)
        {
            var pageCount = items.Any() ? items.Count() : 0;
            var rawUrl = HttpContext.Current.Request.RawUrl;
            var list = items.GetPagedList(pageIndex, pageSize);
            if (StringExtensions.IsNullOrEmpty("page".Q()))
            {
                if (rawUrl.IndexOf("?", StringComparison.Ordinal) > 0)
                {
                    rawUrl += "&page=1";
                }
                else
                {
                    rawUrl += "?page=1";
                }
            }
            var html = GetPage(pageIndex,pageSize, pageCount,rawUrl);
            return new PageResult<T>()
            {
                List = list,
                PageIndex = pageIndex,
                PageSize = pageSize,
                PageCount = pageCount,
                Html = html
            };
        }

        /// <summary>
        /// web分页
        /// </summary>
        /// <param name="page">当前页次</param>
        /// <param name="size">每页条数</param>
        /// <param name="allcount">总数据量</param>
        /// <param name="rawUrl">当前url</param>
        /// <returns></returns>
        public static string GetPage(int page, int size, int allcount, string rawUrl)
        {
            //编码url，防止跨站脚本攻击
            rawUrl = HttpUtility.HtmlEncode(rawUrl);
            var sb = new StringBuilder();
            page = page > 0 ? page : 1;
            //计算总页数
            var pageCount = 0;
            pageCount = allcount % size == 0 ? allcount / size : allcount / size + 1;
            //当前页次
            var pageIndex = page;
            rawUrl = Regex.Replace(rawUrl, @"(p)\d+|(page=)\d+", "$1$2{0}");
            if (pageCount >= 1)
            {
                var p = pageIndex - 1;
                if (pageIndex == 1)
                {
                    sb.Append("<a " + Currentlastpageclass + " >上一页</a>");
                }
                else
                {
                    sb.Append("<a " + Lastpageclass + " href=\"" + string.Format(rawUrl, (p == 0 ? 1 : p)) + "\">上一页</a>");
                }
            }
            if (pageCount <= 10)
            {
                for (int i = 1, l = pageCount + 1; i < l; i++)
                {
                    if (i != pageIndex)
                    {
                        sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, i) + "\">" + i + "</a>");
                    }
                    else
                    {
                        sb.Append("<a " + Currentnumclass + ">" + i + "</a>");
                    }
                }
            }
            else
            {
                if (pageIndex < 6)
                {
                    for (var i = 1; i < 11; i++)
                    {
                        if (i != pageIndex)
                        {
                            sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, i) + "\">" + i + "</a>");
                        }
                        else
                        {
                            sb.Append("<a " + Currentnumclass + ">" + i + "</a>");
                        }
                    }
                }
                else if (pageIndex >= 6 && pageIndex + 4 < pageCount)
                {
                    sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, 1) + "\">" + 1 + "</a>");
                    sb.Append("<a " + Numclass + ">...</a>");
                    for (var i = pageIndex - 3; i < pageIndex + 4; i++)
                    {
                        if (i != pageIndex)
                        {
                            sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, i) + "\">" + i + "</a>");
                        }
                        else
                        {
                            sb.Append("<a " + Currentnumclass + ">" + i + "</a>");
                        }
                    }
                    sb.Append("<a " + Numclass + ">...</a>");
                    sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, pageCount) + "\">" + pageCount + "</a>");
                }
                else if (pageIndex >= 6 && pageIndex + 4 >= pageCount)
                {
                    sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, 1) + "\">" + 1 + "</a>");
                    sb.Append("<a " + Numclass + ">...</a>");
                    for (int i = pageIndex - 3, l = pageCount + 1; i < l; i++)
                    {
                        if (i != pageIndex)
                        {
                            sb.Append("<a " + Numclass + " href=\"" + string.Format(rawUrl, i) + "\">" + i + "</a>");
                        }
                        else
                        {
                            sb.Append("<a " + Currentnumclass + ">" + i + "</a>");
                        }
                    }
                }
            }
            if (pageCount >= 1)
            {
                var p = pageIndex + 1;
                if (pageIndex == pageCount)
                {
                    sb.Append("<a " + Currentnextpageclass + ">下一页</a>");
                }
                else
                {
                    sb.Append("<a " + Nextpageclass + " href=\"" + string.Format(rawUrl, (p > pageCount ? pageCount : p)) + "\">下一页</a>");
                }
            }
            if (allcount > 0)
            {
                var sb2 = new StringBuilder();
                sb2.Append("<span class=\"select-boxp\"><label>跳转至</label><select class=\"select-no\" id=\"topageselect\">");
                for (var i = 1; i < pageCount + 1; i++)
                {
                    sb2.Append(page == i
                        ? $"<option value=\"{string.Format(rawUrl, i)}\" selected=\"\">第{i}页</option>"
                        : $"<option value=\"{string.Format(rawUrl, i)}\">第{i}页</option>");
                }
                sb2.Append("</select><label class=\"avx\"  onclick=\"topageurl()\">确定</label></span>");
                return "<span class=\"infoall\">总计" + allcount + "条记录</span>" + sb + sb2;
            }
            else
            {
                return "<span class=\"infoall\">总计" + allcount + "条记录</span>" + sb;
            }
        }


        /// <summary>
        /// LayUI分页
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static LayPageResult<T> GetLayPage<T>(this List<T> items, int pageIndex, int pageSize)
        {
            var pageCount = items.Any() ? items.Count() : 0;
            var list = items.GetPagedList(pageIndex, pageSize);
            return new LayPageResult<T>()
            {
                code = 1,
                msg = "数据获取成功",
                count = pageCount,
                data = list
            };
        }

    }

    public class PageResult<T>
    {
        /// <summary>
        /// 分页数据
        /// </summary>
        public List<T> List { get; set; }

        /// <summary>
        /// 当前页数
        /// </summary>
        public int PageIndex { get; set; }

        /// <summary>
        /// 分页大小
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// 总页数
        /// </summary>
        public int PageCount { get; set; }

        /// <summary>
        /// 分页按钮代码
        /// </summary>
        public string Html { get; set; }

    }

    public class LayPageResult<T>
    {
        public int code { get; set; }

        public string msg { get; set; }

        public int count { get; set; }

        public List<T> data { get; set; }

    }

}
